#include <QMessageBox>
#include "kubs.h"

extern "C"
{


extern int lmeklet(char * rez,char * poz) asm("lmeklet");

}



const  int kubs::krasas[][3] =  {{1,0,0},{0,1,0},{0,0,1},{1,1,0},{0,1,1},{1,0,1}};


const float kubs::malas[][4][3] =
{
{{0,0,0.5},{-0.5,0,0.5},{-0.5,0.5,0.5},{0,0.5,0.5}},
{{0,0,0.5},{0,0.5,0.5},{0.5,0.5,0.5},{0.5,0,0.5}},
{{0,0,0.5},{0.5,0,0.5},{0.5,-0.5,0.5},{0,-0.5,0.5}},
{{0,0,0.5},{0,-0.5,0.5},{-0.5,-0.5,0.5},{-0.5,0,0.5}},

{{0,0,-0.5},{-0.5,0,-0.5},{-0.5,0.5,-0.5},{0,0.5,-0.5}},
{{0,0,-0.5},{0,0.5,-0.5},{0.5,0.5,-0.5},{0.5,0,-0.5}},
{{0,0,-0.5},{0.5,0,-0.5},{0.5,-0.5,-0.5},{0,-0.5,-0.5}},
{{0,0,-0.5},{0,-0.5,-0.5},{-0.5,-0.5,-0.5},{-0.5,0,-0.5}},

{{0.5,0,0},{0.5,-0.5,0},{0.5,-0.5,0.5},{0.5,0,0.5}},
{{0.5,0,0},{0.5,0,0.5},{0.5,0.5,0.5},{0.5,0.5,0}},
{{0.5,0,0},{0.5,0.5,0},{0.5,0.5,-0.5},{0.5,0,-0.5}},
{{0.5,0,0},{0.5,0,-0.5},{0.5,-0.5,-0.5},{0.5,-0.5,0}},

{{-0.5,0,0},{-0.5,-0.5,0},{-0.5,-0.5,0.5},{-0.5,0,0.5}},
{{-0.5,0,0},{-0.5,0,0.5},{-0.5,0.5,0.5},{-0.5,0.5,0}},
{{-0.5,0,0},{-0.5,0.5,0},{-0.5,0.5,-0.5},{-0.5,0,-0.5}},
{{-0.5,0,0},{-0.5,0,-0.5},{-0.5,-0.5,-0.5},{-0.5,-0.5,0}},

{{0,0.5,0},{-0.5,0.5,0},{-0.5,0.5,0.5},{0,0.5,0.5}},
{{0,0.5,0},{0,0.5,0.5},{0.5,0.5,0.5},{0.5,0.5,0}},
{{0,0.5,0},{0.5,0.5,0},{0.5,0.5,-0.5},{0,0.5,-0.5}},
{{0,0.5,0},{0,0.5,-0.5},{-0.5,0.5,-0.5},{-0.5,0.5,0}},

{{0,-0.5,0},{-0.5,-0.5,0},{-0.5,-0.5,0.5},{0,-0.5,0.5}},
{{0,-0.5,0},{0,-0.5,0.5},{0.5,-0.5,0.5},{0.5,-0.5,0}},
{{0,-0.5,0},{0.5,-0.5,0},{0.5,-0.5,-0.5},{0,-0.5,-0.5}},
{{0,-0.5,0},{0,-0.5,-0.5},{-0.5,-0.5,-0.5},{-0.5,-0.5,0}}

};



const int kubs::simpag[][24]= {
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23},
{1,2,3,0,5,6,7,4,20,21,22,23,16,17,18,19,9,8,11,10,13,12,15,14},
{3,0,1,2,7,4,5,6,17,16,19,18,21,20,23,22,12,13,14,15,8,9,10,11},
{2,3,0,1,6,7,4,5,13,12,15,14,9,8,11,10,21,20,23,22,17,16,19,18},
{5,4,7,6,1,0,3,2,15,14,13,12,11,10,9,8,18,19,16,17,22,23,20,21},
{4,7,6,5,0,3,2,1,22,23,20,21,18,19,16,17,14,15,12,13,10,11,8,9},
{6,5,4,7,2,1,0,3,19,18,17,16,23,22,21,20,11,10,9,8,15,14,13,12},
{7,6,5,4,3,2,1,0,10,11,8,9,14,15,12,13,23,22,21,20,19,18,17,16},
{9,10,11,8,13,14,15,12,6,5,4,7,2,1,0,3,17,18,19,16,21,22,23,20},
{10,11,8,9,14,15,12,13,21,22,23,20,17,18,19,16,5,6,7,4,1,2,3,0},
{8,9,10,11,12,13,14,15,18,17,16,19,22,21,20,23,2,1,0,3,6,5,4,7},
{11,8,9,10,15,12,13,14,1,2,3,0,5,6,7,4,22,21,20,23,18,17,16,19},
{14,13,12,15,10,9,8,11,3,0,1,2,7,4,5,6,19,16,17,18,23,20,21,22},
{13,12,15,14,9,8,11,10,23,20,21,22,19,16,17,18,0,3,2,1,4,7,6,5},
{15,14,13,12,11,10,9,8,16,19,18,17,20,23,22,21,7,4,5,6,3,0,1,2},
{12,15,14,13,8,11,10,9,4,7,6,5,0,3,2,1,20,23,22,21,16,19,18,17},
{19,18,17,16,23,22,21,20,9,10,11,8,13,14,15,12,4,5,6,7,0,1,2,3},
{18,17,16,19,22,21,20,23,0,1,2,3,4,5,6,7,10,9,8,11,14,13,12,15},
{16,19,18,17,20,23,22,21,5,4,7,6,1,0,3,2,13,14,15,12,9,10,11,8},
{17,16,19,18,21,20,23,22,14,13,12,15,10,9,8,11,1,0,3,2,5,4,7,6},
{20,21,22,23,16,17,18,19,11,8,9,10,15,12,13,14,3,2,1,0,7,6,5,4},
{21,22,23,20,17,18,19,16,7,6,5,4,3,2,1,0,8,11,10,9,12,15,14,13},
{23,20,21,22,19,16,17,18,2,3,0,1,6,7,4,5,15,12,13,14,11,8,9,10},
{22,23,20,21,18,19,16,17,12,15,14,13,8,11,10,9,6,7,4,5,2,3,0,1}
};




const int kubs::pagriezieni[][24] ={
{3,0,1,2,4,5,6,7,17,16,10,11,21,20,14,15,12,13,18,19,8,9,22,23},
{0,1,2,3,5,6,7,4,8,9,22,23,12,13,18,19,16,17,11,10,20,21,15,14},
{0,21,22,3,4,17,18,7,11,8,9,10,12,13,14,15,16,2,1,19,20,6,5,23},
{19,1,2,16,23,5,6,20,8,9,10,11,13,14,15,12,4,17,18,7,0,21,22,3},
{9,10,2,3,13,14,6,7,8,5,4,11,12,1,0,15,17,18,19,16,20,21,22,23},
{0,1,12,15,4,5,8,11,3,9,10,2,7,13,14,6,16,17,18,19,23,20,21,22},
{1,2,3,0,4,5,6,7,20,21,10,11,16,17,14,15,9,8,18,19,13,12,22,23},
{0,1,2,3,7,4,5,6,8,9,19,18,12,13,23,22,16,17,14,15,20,21,10,11},
{0,18,17,3,4,22,21,7,9,10,11,8,12,13,14,15,16,5,6,19,20,1,2,23},
{20,1,2,23,16,5,6,19,8,9,10,11,15,12,13,14,3,17,18,0,7,21,22,4},
{14,13,2,3,10,9,6,7,8,0,1,11,12,4,5,15,19,16,17,18,20,21,22,23},
{0,1,11,8,4,5,15,12,6,9,10,7,2,13,14,3,16,17,18,19,21,22,23,20}
};

const int kubs::sturuvietas[][8]=
{
{0,3,2,1,4,7,6,5},
{1,0,3,2,5,4,7,6},
{2,1,0,3,6,5,4,7},
{3,2,1,0,7,6,5,4},
{4,7,6,5,0,3,2,1},
{5,4,7,6,1,0,3,2},
{6,5,4,7,2,1,0,3},
{7,6,5,4,3,2,1,0}
};





const int kubs::sturi[][3]=
{
{1,9,17},
{0,16,13},
{3,12,20},
{2,21,8},
{5,10,18},
{4,19,14},
{7,15,23},
{6,22,11}
};

const int kubs::sturip[][3]=
{
{ 0, 2, 4},
{ 0, 4, 3},
{ 0, 3, 5},
{ 0, 5, 2},
{ 1, 2, 4},
{ 1, 4, 3},
{ 1, 3, 5},
{ 1, 5, 2}
};


 Matrix4fT  kubs::mTransform   = {  1.0f,  0.0f,  0.0f,  0.0f,
                        0.0f,  1.0f,  0.0f,  0.0f,
                        0.0f,  0.0f,  1.0f,  0.0f,
                        0.0f,  0.0f,  0.0f,  1.0f };


 Matrix3fT   kubs::LastRot     = {  1.0f,  0.0f,  0.0f,
                              0.0f,  1.0f,  0.0f,
                              0.0f,  0.0f,  1.0f };

 Matrix3fT   kubs::ThisRot     = {  1.0f,  0.0f,  0.0f,
                              0.0f,  1.0f,  0.0f,
                              0.0f,  0.0f,  1.0f };





  kubs::kubs(QWidget *parent)
         : QGLWidget(parent)
{
      ArcBall = new ArcBallT(300.0,300.0);
              isClicked  = false;

          isDragging = false;

gajsk = 0;

}





void kubs::sakartot()
{

for (int i = 0;i!=24;i++)vietas[i] = i;
    cuberotated(25);
     updateGL();
}



void kubs::zimet()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();
glTranslatef(0, 0,-4);




glMultMatrixf(mTransform.M);







for (int i = 0;i!=24;i++)
{
int re,gr,bl;
re = krasas[vietas[i]>>2][0];
gr = krasas[vietas[i]>>2][1];
bl = krasas[vietas[i]>>2][2];
 glColor3f(re,gr, bl);
 glBegin(GL_POLYGON);
 glVertex3f(malas[i][0][0],malas[i][0][1],malas[i][0][2]);
 glVertex3f(malas[i][1][0],malas[i][1][1],malas[i][1][2]);
 glVertex3f(malas[i][2][0],malas[i][2][1],malas[i][2][2]);
 glVertex3f(malas[i][3][0],malas[i][3][1],malas[i][3][2]);
 glEnd();
}

 glColor3f(1,0, 0);
 glBegin(GL_POLYGON);
 glVertex3f(-0.1,-0.1,0.51);
glVertex3f(-0.1,0.1,0.51);
glVertex3f(0.1,0.1,0.51);
glVertex3f(0.1,-0.1,0.51);
glEnd();

 glColor3f(0,1, 0);
 glBegin(GL_POLYGON);
 glVertex3f(-0.1,-0.1,-0.51);
glVertex3f(-0.1,0.1,-0.51);
glVertex3f(0.1,0.1,-0.51);
glVertex3f(0.1,-0.1,-0.51);
glEnd();


 glColor3f(0,0,1);
 glBegin(GL_POLYGON);
 glVertex3f(0.51,-0.1,-0.1);
glVertex3f(0.51,-0.1,0.1);
glVertex3f(0.51,0.1,0.1);
glVertex3f(0.51,0.1,-0.1);
glEnd();



glColor3f(1,1, 0);
glBegin(GL_POLYGON);
glVertex3f(-0.51,-0.1,-0.1);
glVertex3f(-0.51,-0.1,0.1);
glVertex3f(-0.51,0.1,0.1);
glVertex3f(-0.51,0.1,-0.1);
glEnd();


glColor3f(0,1,1);
glBegin(GL_POLYGON);
glVertex3f(-0.1,0.51,-0.1);
glVertex3f(-0.1,0.51,0.1);
glVertex3f(0.1,0.51,0.1);
glVertex3f(0.1,0.51,-0.1);
glEnd();



glColor3f(1,0, 1);
glBegin(GL_POLYGON);
glVertex3f(-0.1,-0.51,-0.1);
glVertex3f(-0.1,-0.51,0.1);
glVertex3f(0.1,-0.51,0.1);
glVertex3f(0.1,-0.51,-0.1);
glEnd();


glFlush();


}


void kubs::pagriezt(int pagr)
{
int buf[24];

for (int i = 0;i!=24;i++)buf[i]=vietas[pagriezieni[pagr][i]];
for (int i = 0;i!=24;i++)vietas[i]=buf[i];

  updateGL();
    cuberotated(pagr);

}


void kubs::simgr(int pagr)
{
int buf[24];
for (int i = 0;i!=24;i++)buf[i]=simpag[pagr][vietas[i]];
for (int i = 0;i!=24;i++)vietas[simpag[pagr][i]]=buf[i];

  cuberotated(24);
}




void kubs::invert()
{
int buf[24];

for (int i = 0;i!=24;i++)buf[vietas[i]] = i;
for (int i = 0;i!=24;i++)vietas[i] = buf[i];

}

void kubs::meklet()
{

int rezu;
for (int i = 0;i!=24;i++)poz[i]=vietas[i];
rezu = lmeklet(rez,poz);

for(int i = 0;i!=rezu+1;i++)
{
 int gaj = rez[rezu-i]/3;
 gaj = gaj > 5 ? gaj -6 : gaj + 6;
    gajieni[i]=gaj ;
}

QMessageBox::information ( this, QString("Meklēšana pabeigta!") ,
                           QString("Atrasts ar %1 gājieniem").arg(rezu+1)) ;

gajsk=rezu+1;
}

int kubs::salidz(int * viet)
{
int rez = 24;
for(int i = 0;i!=24;i++)if(vietas[i]==viet[i])rez--;
return rez;
}

void kubs::kombinet(int * viet )
{
int pag[24];
for(int i = 0;i!=24;i++)pag[i]= vietas[viet[i]];
for(int i = 0;i!=24;i++)vietas[i] = pag[i];
cuberotated(25);
   updateGL();
}

void kubs::atrsturus()
{

for(int i=0;i<8;i++)
{
    int j,k;
    for( k=0;k<8;k++)
    {
        for(j=0;j<3;j++)if(sturi[k][0] == vietas[sturi[i][j]])break;
    if(j<3)break;

    }

    vsturi[i] = 3*k+j;

    }
}











  void kubs::initializeGL()
     {


       glClearColor(0.0, 0.0, 0.0, 0.0);
         glEnable(GL_DEPTH_TEST);

     }


     void kubs::resizeGL(int w, int h)
     {


if (w < 10 || h < 10) QMessageBox::warning ( this, QString("Nevar attēlot!") ,
                           QString("Par mazu laukuma izmēri")) ;

else
{

glEnable(GL_DEPTH_TEST);
if  (w > h)
{
    glViewport(0,0,h,h);
    centrsx=h/2;
    centrsy=h/2;
}
    else
{
        glViewport(0,0,w,w);
    centrsx=w/2;
    centrsy=w/2;


    }
        glClearColor(0.0, 0.0, 0.0, 0.0);
glClearDepth(20);

   glMatrixMode(GL_PROJECTION);
glLoadIdentity();

 glFrustum (-0.6, 0.6, -0.6, 0.6 ,2 , 40.0);
glMatrixMode(GL_MODELVIEW);
ArcBall->setBounds(2*centrsx,2*centrsy);
zimet();


}





     }


        void kubs::paintGL()
     {

     zimet();

        }

 void kubs::mousePressEvent(QMouseEvent *event)
 {
     if (event->button() == Qt::LeftButton) {


         isDragging = true;										// Prepare For Dragging
                                 LastRot = ThisRot;
                                 // Set Last Static Rotation To Last Dynamic One
                                   MousePt.s.Y =event->posF().y();
                                     MousePt.s.X =event->posF().x();
                                 ArcBall->click(&MousePt);



    ispressed = true;


}
 }

 double kubs::truetg(int y,int  x)
 {


 if (x==0 )
     {
   if (y >0) return 90;
    else return 270;

 }
 else{
 double smangl = atan((double)abs(y)/(double)abs(x))*180/M_PI;
 if (x>0)
 {
 if(y>0) return smangl;
 else return 360 - smangl ;
 }
 else
 {
 if(y>0) return 180 - smangl;
 else return smangl + 180;

 }
}
}



 double kubs::truetgd(double y,double  x)
 {


 if (x==0 )
     {
   if (y >0) return 90;
    else return 270;

 }
 else{
 double smangl = atan(fabs(y)/fabs(x))*180/M_PI;

 if (x>0)
 {
 if(y>0) return smangl;
 else return 360 - smangl ;
 }
 else
 {
 if(y>0) return 180 - smangl;
 else return smangl + 180;

 }
}
}


 void kubs::mouseMoveEvent(QMouseEvent *event)
 {


     if ((event->buttons() & Qt::LeftButton) && ispressed)
     {


         MousePt.s.Y =event->posF().y();
           MousePt.s.X =event->posF().x();
      Quat4fT     ThisQuat;

         ArcBall->drag(&MousePt, &ThisQuat);						// Update End Vector And Get Rotation As Quaternion
         Matrix3fSetRotationFromQuat4f(&ThisRot, &ThisQuat);		// Convert Quaternion Into Matrix3fT
         Matrix3fMulMatrix3f(&ThisRot, &LastRot);				// Accumulate Last Rotation Into This One
         Matrix4fSetRotationFromMatrix3f(&mTransform, &ThisRot);	// Set Our Final Transform's Rotation From This One





 updateGL();
anglech();
}
    // zimet();
 }

 void kubs::mouseReleaseEvent(QMouseEvent *event)
 {
     if (event->button() == Qt::LeftButton && ispressed)
     {
         {

  isDragging = false;


anglech();



  }
         ispressed = false;
     }
      showpos(event->pos().x(),event->pos().y());
 }



   void kubs::sark()
   {
pagriezt(0);

   }
    void kubs::zals()
    {
pagriezt(1);
    }
    void kubs::zils()
    {
pagriezt(2);
   }
    void kubs::dzelt()
    {
pagriezt(3);

   }
    void kubs::cian()
    {
pagriezt(4);
   }
    void kubs::viol()
    {
pagriezt(5);
   }
    void kubs::sarkm()
    {
pagriezt(6);
   }
    void kubs::zalsm()
    {
pagriezt(7);
   }
    void kubs::zilsm()
    {
pagriezt(8);
   }
    void kubs::dzeltm()
    {
pagriezt(9);
   }
    void kubs::cianm()
    {
pagriezt(10);
   }
    void kubs::violm()
    {
pagriezt(11);
   }


